# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +---------------------------------------------------------------------
import time
from tortoise.expressions import Q
from hypertext import PagingResult
from common.utils.urls import UrlUtil
from common.enums.notice import NoticeEnum
from common.models.users import UserModel
from common.models.music import MusicRecordsModel
from plugins.msg.driver import MsgDriver
from apps.admin.schemas.apply.music import record_schema as schema


class MusicRecordService:

    @classmethod
    async def lists(cls, params: schema.MusicRecordSearchIn) -> PagingResult[schema.MusicRecordVo]:
        """
        音乐记录列表

        Args:
            params (schemas.MusicRecordSearchIn): 搜索参数

        Returns:
            PagingResult[schema.MusicRecordVo]

        Author:
            zero
        """
        # 查询条件
        where = MusicRecordsModel.build_search({
            "=": ["mode", "status"],
            "%like%": ["prompt"],
            "datetime": ["start_time|end_time@create_time"]
        }, params.__dict__)

        where.append(Q(is_delete=0))
        if params.user_sn:
            user = await UserModel.filter(sn=str(params.user_sn)).first().values("id") or {}
            where.append(Q(user_id=user.get(str("id"), 0)))

        # 查询数据
        _model = MusicRecordsModel.filter(*where).order_by(str("-id"))
        _pager = await MusicRecordsModel.paginate(
            page_no=params.page_no,
            page_size=params.page_size,
            model=_model
        )

        # 所属用户
        user_ids = [int(item["user_id"]) for item in _pager.lists if item["user_id"]]
        users: dict = await UserModel.queryUserDictsById(user_ids)

        _lists = []
        for item in _pager.lists:
            user = users.get(item["user_id"], {})
            _lists.append(schema.MusicRecordVo(
                id=item["id"],
                code=item["code"],
                mode=item["mode"],
                engine=item["engine"],
                channel=item["channel"],
                title=item["title"],
                prompt=item["prompt"],
                tags=item["tags"] or "-",
                mv=item["mv"] or "-",
                make_instrumental=bool(item["make_instrumental"]),
                cover_url=await UrlUtil.to_absolute_url(item["cover_url"]),
                audio_url=await UrlUtil.to_absolute_url(item["audio_url"]),
                lyric=item["lyric"],
                duration=item["duration"],
                use_points=item["use_points"],
                ip=item["ip"],
                status=item["status"],
                is_free=item["is_free"],
                fail_reason=item["fail_reason"] or "",
                create_time=item["create_time"],
                user={
                    "sn": user.get("sn", "").strip(),
                    "nickname": user.get("nickname", ""),
                    "mobile": user.get("mobile", ""),
                    "avatar": await UrlUtil.to_absolute_url(user.get("avatar", ""))
                }
            ))

        _pager.lists = _lists
        return _pager

    @classmethod
    async def delete(cls, id_: int, reason: str) -> None:
        """
        音乐记录删除

        Args:
            id_ (int): ID
            reason (str): 原因描述

        Author:
            zero
        """
        record = await MusicRecordsModel.filter(id=id_, is_delete=0).get()
        await MusicRecordsModel.filter(id=id_).update(
            is_delete=1,
            delete_time=int(time.time())
        )

        # 发送用户通知
        await MsgDriver.send(scene=NoticeEnum.MUSIC_DELETE, params={
            "user_id": record.user_id,
            "code": record.code,
            "title": record.title,
            "prompt": record.prompt,
            "reason": reason
        })
